import os.path
import zipfile
from PyQt5.QtCore import QEvent
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QGroupBox, QHBoxLayout, QLabel, QComboBox, QPushButton, QMessageBox, \
     QFileDialog
from LanguageTool import getCNfromDict
from LisenceTool import getActStatus
from UDiskTool import format_usb_drive, get_usb_drives
from fileOpTool import upgradeThread
from mylog import addLog
from progressWindow import ProgressDialog


class TabBar03(QWidget):
    orgPath_iflytek = "./res/iflytek.zip"
    curPath_iflytek = ""
    orgPath_spiFlashUpdate = "./res/SpiFlashUpdate.zip"
    curPath_spiFlashUpdate = ""

    def __init__(self):
        super().__init__()

        # 创建垂直布局
        layout = QVBoxLayout()

        # 添加第一个 QGroupBox
        group_box_1 = self.GroupBox_format()
        layout.addWidget(group_box_1)

        # 添加第一个 QGroupBox
        group_box_2 = self.GroupBox_iflytek()
        layout.addWidget(group_box_2)

        # 添加第一个 QGroupBox
        group_box_3 = self.GroupBox_spiFlashUpdate()
        layout.addWidget(group_box_3)

        # 将主布局设置到窗口中
        self.setLayout(layout)

        # 创建解压线程
        self.upgrade_thread = None
        # 创建进度弹窗
        self.progress_dialog = None

    def GroupBox_format(self):
        group_box = QGroupBox(getCNfromDict('TabBar03-gb-format'))  # 创建 QGroupBox
        group_box.setMaximumHeight(100)

        # 创建一个水平布局，用于放置标签和下拉列表和按钮
        h_layout = QHBoxLayout()
        # 添加一个标签
        label = QLabel(getCNfromDict('TabBar03-gb-disk'))
        label.setMaximumWidth(100)

        # 添加一个下拉列表
        self.combo_box = QComboBox(self)
        self.combo_box.setMaximumWidth(500)
        self.combo_box.addItems([" "])

        self.combo_box1 = QComboBox(self)
        self.combo_box1.setMaximumWidth(150)
        self.combo_box1.addItems(["exFAT", "FAT32"])

        # 安装事件过滤器
        self.combo_box.installEventFilter(self)

        self.run_btn = QPushButton(getCNfromDict('TabBar03-gb-run'), self)
        self.run_btn.setMaximumWidth(100)
        self.run_btn.clicked.connect(self.run_btn_clicked)

        self.build_btn = QPushButton(getCNfromDict('TabBar03-gb-build'), self)
        self.build_btn.setMaximumWidth(100)
        self.build_btn.clicked.connect(self.build_btn_clicked)

        if getActStatus():
            self.run_btn.setEnabled(True)
            self.build_btn.setEnabled(True)
        else:
            self.run_btn.setEnabled(False)
            self.build_btn.setEnabled(False)

        h_layout.addWidget(label)
        h_layout.addWidget(self.combo_box)
        h_layout.addWidget(self.combo_box1)
        h_layout.addWidget(self.run_btn)
        h_layout.addWidget(self.build_btn)

        # self.tips_label = QLabel()

        # 创建一个垂直布局，用于放置水平布局和标签
        v_layout = QVBoxLayout()
        v_layout.addLayout(h_layout)

        # 将水平布局设置为 QGroupBox 的布局
        group_box.setLayout(v_layout)

        return group_box

    def run_btn_clicked(self):
        addLog('TabBar03', 'info', f"run_btn_clicked")
        # print(str(self.combo_box.currentIndex()) + " : " + self.combo_box.currentText())
        if self.combo_box.currentText() == " ":
            addLog('TabBar03', 'info', f"no U-Disk")
            return

        drive_letter = self.combo_box.currentText().split('[')[0].replace(' ', '')
        fmt = self.combo_box1.currentText()
        # print(drive_letter)
        # 弹窗提示是否格式化该U盘
        reply = QMessageBox.question(self, getCNfromDict('TabBar03-gb-runmsg'),
                                     getCNfromDict('TabBar03-gb-runmsgcontent').replace('{U}', drive_letter).replace(
                                         '{F}', fmt),
                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

        if reply == QMessageBox.Yes:
            if format_usb_drive(drive_letter, fmt) == 0:
                self.scanUDisk()
                # 弹窗提示格式化完成
                self.show_message(getCNfromDict('TabBar03-gb-runmsgsucc'), 0)
                addLog('TabBar03', 'info', f"U-Disk formate finished")
            else:
                # 弹窗提示格式化失败
                self.show_message(getCNfromDict('TabBar03-gb-runmsgerr'), 1)
                addLog('TabBar03', 'warn', f"U-Disk formate failed")
        return

    def build_btn_clicked(self):
        addLog('TabBar03', 'info', f"build_btn_clicked")
        # 判断U盘是否选择、是否存在
        if self.combo_box.currentText() == " ":
            self.show_message(getCNfromDict('TabBar03-gb-buildmsgerr1'), 1)
            addLog('TabBar03', 'warn', f"no choose U-Disk")
            return

        ufmt = self.combo_box.currentText().split('[')[1].split(']')[0]
        if ufmt not in ['exFAT', 'FAT32']:
            self.show_message(getCNfromDict('TabBar03-gb-buildmsgerr2'), 1)
            addLog('TabBar03', 'warn', f"U-Disk filesystem error")
            return

        drive_letter = self.combo_box.currentText().split('[')[0].replace(' ', '')
        drive_path = f"{drive_letter}/"
        if not os.path.exists(drive_path):
            self.show_message(getCNfromDict('TabBar03-gb-buildmsgerr3'), 1)
            addLog('TabBar03', 'warn', f"U-Disk can`t visit")
            return

        # 先判断原厂包、两个升级包是否存在
        if self.curPath_iflytek != "":
            if not os.path.exists(self.curPath_iflytek):
                self.show_message(getCNfromDict('TabBar03-gb-buildmsgerr4'), 1)
                addLog('TabBar03', 'warn', f"iflytek pack not found")
                return

        if self.curPath_spiFlashUpdate != "":
            if not os.path.exists(self.curPath_spiFlashUpdate):
                self.show_message(getCNfromDict('TabBar03-gb-buildmsgerr5'), 1)
                addLog('TabBar03', 'warn', f"spiFlashUpdate pack not found")
                return

        # 创建线程复制操作
        # 创建解压线程
        self.upgrade_thread = upgradeThread(drive_path, self.curPath_iflytek, self.curPath_spiFlashUpdate)
        # 创建进度弹窗
        self.progress_dialog = ProgressDialog(getCNfromDict('TabBar03-btnbuilding'), self)
        self.progress_dialog.show()
        # 连接信号和槽
        self.upgrade_thread.progress_signal.connect(self.progress_dialog.update_progress)
        self.upgrade_thread.status_signal.connect(self.btnbuild_status)
        self.upgrade_thread.status_signal.connect(self.progress_dialog.update_status)
        # 启动线程
        self.upgrade_thread.start()
        addLog('TabBar03', 'info', f"start upgrade")

    def btnbuild_status(self, status):
        """
                更新状态信息。
        """
        if status == 0:
            self.show_message(getCNfromDict('TabBar03-btnbuildsuc'), 1)
            addLog('TabBar03', 'info', f"upgrade finish")
        else:
            self.show_message(getCNfromDict('TabBar03-btnbuilderr'), 1)
            addLog('TabBar03', 'error', f"upgrade error")

    def GroupBox_iflytek(self):
        group_box = QGroupBox(getCNfromDict('TabBar03-gb-iflytek'))

        h_layout = QHBoxLayout()

        self.iflytek_btn = QPushButton(getCNfromDict('TabBar03-gb-btn_choosezip'), self)
        self.iflytek_btn.setFixedHeight(30)
        self.iflytek_btn.setFixedWidth(150)
        self.iflytek_btn.clicked.connect(self.iflytek_btn_clicked)
        self.iflytek_label = QLabel(self.orgPath_iflytek, self)
        self.iflytek_label.setFixedHeight(30)

        h_layout.addWidget(self.iflytek_btn)
        h_layout.addWidget(self.iflytek_label)

        # tab = QWidget()
        # # 创建滚动区域
        # scroll_area = QScrollArea(tab)
        # scroll_area.setWidgetResizable(True)  # 允许滚动区域大小变化
        # # 创建滚动区域内的容器
        # container_widget = QWidget()
        # scroll_area.setWidget(container_widget)
        # # 创建容器的布局
        # self.iflytek_layout = QVBoxLayout(container_widget)
        # self.iflytek_layout.setSpacing(0)
        # self.iflytek_layout.setContentsMargins(0, 0, 0, 0)
        # # 将滚动区域添加到标签页的布局中
        # tab_layout = QVBoxLayout(tab)
        # tab_layout.addWidget(scroll_area)
        # tab.setLayout(tab_layout)
        #
        # # todo::self.iflytek_layout.addWidget(IflytekUnit)

        # 创建一个垂直布局，用于放置水平布局和标签
        v_layout = QVBoxLayout()
        v_layout.addLayout(h_layout)
        # v_layout.addWidget(tab)

        # 将水平布局设置为 QGroupBox 的布局
        group_box.setLayout(v_layout)
        return group_box

    def iflytek_btn_clicked(self):
        addLog('TabBar03', 'info', f"iflytek_btn_clicked")
        if self.iflytek_label.text() == self.orgPath_iflytek:
            # 选择一个zip压缩包
            file_path, _ = QFileDialog.getOpenFileName(self,
                                                       getCNfromDict('TabBar05-btnimportwindow'),
                                                       "./generate/kedaxunfei",
                                                       "ZIP Files (*.zip)")
            if file_path:
                addLog('TabBar03', 'info', f"Selected file: {file_path}")
                with zipfile.ZipFile(file_path, 'r') as zip_ref:
                    # 获取 ZIP 文件中的所有文件名
                    file_list = zip_ref.namelist()
                    print(file_list)
                    # 判断ZIP目录结构是否有效
                    if 'ica/sound_data_versions.txt' in file_list:
                        # 有效的数据包
                        self.curPath_iflytek = file_path
                        self.iflytek_label.setText(file_path)
                        self.iflytek_label.setStyleSheet("color: blue")
                        self.iflytek_btn.setText(getCNfromDict('TabBar03-gb-btn_unchoosezip'))
                        addLog('TabBar03', 'info', f"{file_path} is vaild iflytek pack")
                    else:
                        self.show_message(getCNfromDict('TabBar03-gb-btn_ziperr'), 1)
                        addLog('TabBar03', 'warn', f"{file_path} is unvaild iflytek pack")
        else:
            self.iflytek_btn.setText(getCNfromDict('TabBar03-gb-btn_choosezip'))
            self.iflytek_label.setText(self.orgPath_iflytek)
            self.iflytek_label.setStyleSheet("color: black")
            self.curPath_iflytek = ""
            addLog('TabBar03', 'info', f"cancel iflytek pack")

    def GroupBox_spiFlashUpdate(self):
        group_box = QGroupBox(getCNfromDict('TabBar03-gb-spiFlashUpdate'))
        h_layout = QHBoxLayout()

        self.spiFlashUpdate_btn = QPushButton(getCNfromDict('TabBar03-gb-btn_choosezip'), self)
        self.spiFlashUpdate_btn.setFixedHeight(30)
        self.spiFlashUpdate_btn.setFixedWidth(150)
        self.spiFlashUpdate_btn.clicked.connect(self.spiFlashUpdate_btn_clicked)
        self.spiFlashUpdate_label = QLabel(self.orgPath_spiFlashUpdate, self)
        self.spiFlashUpdate_label.setFixedHeight(30)

        h_layout.addWidget(self.spiFlashUpdate_btn)
        h_layout.addWidget(self.spiFlashUpdate_label)

        # tab = QWidget()
        # # 创建滚动区域
        # scroll_area = QScrollArea(tab)
        # scroll_area.setWidgetResizable(True)  # 允许滚动区域大小变化
        # # 创建滚动区域内的容器
        # container_widget = QWidget()
        # scroll_area.setWidget(container_widget)
        # # 创建容器的布局
        # self.spiFlashUpdate_layout = QVBoxLayout(container_widget)
        # self.spiFlashUpdate_layout.setSpacing(0)
        # self.spiFlashUpdate_layout.setContentsMargins(0, 0, 0, 0)
        # # 将滚动区域添加到标签页的布局中
        # tab_layout = QVBoxLayout(tab)
        # tab_layout.addWidget(scroll_area)
        # tab.setLayout(tab_layout)
        #
        # # todo::self.spiFlashUpdate_layout.addWidget(IflytekUnit)

        # 创建一个垂直布局，用于放置水平布局和标签
        v_layout = QVBoxLayout()
        v_layout.addLayout(h_layout)
        # v_layout.addWidget(tab)

        # 将水平布局设置为 QGroupBox 的布局
        group_box.setLayout(v_layout)
        return group_box

    def spiFlashUpdate_btn_clicked(self):
        addLog('TabBar03', 'info', f"spiFlashUpdate_btn_clicked")
        if self.spiFlashUpdate_label.text() == self.orgPath_spiFlashUpdate:
            # 选择一个zip压缩包
            file_path, _ = QFileDialog.getOpenFileName(self,
                                                       getCNfromDict('TabBar05-btnimportwindow'),
                                                       "./generate/mcu",
                                                       "ZIP Files (*.zip)")
            if file_path:
                addLog('TabBar03', 'info', f"Selected file: {file_path}")
                with zipfile.ZipFile(file_path, 'r') as zip_ref:
                    # 获取 ZIP 文件中的所有文件名
                    file_list = zip_ref.namelist()
                    # print(file_list)
                    # 判断ZIP目录结构是否有效
                    if 'files/SpiFlashInfo.xml' in file_list:
                        # 有效的数据包
                        self.curPath_spiFlashUpdate = file_path
                        self.spiFlashUpdate_label.setText(file_path)
                        self.spiFlashUpdate_label.setStyleSheet("color: blue")
                        self.spiFlashUpdate_btn.setText(getCNfromDict('TabBar03-gb-btn_unchoosezip'))
                        addLog('TabBar03', 'info', f"{file_path} is vaild spiFlashUpdate pack")
                    else:
                        self.show_message(getCNfromDict('TabBar03-gb-btn_ziperr'), 1)
                        addLog('TabBar03', 'warn', f"{file_path} is unvaild spiFlashUpdate pack")
        else:
            self.spiFlashUpdate_btn.setText(getCNfromDict('TabBar03-gb-btn_choosezip'))
            self.spiFlashUpdate_label.setText(self.orgPath_spiFlashUpdate)
            self.spiFlashUpdate_label.setStyleSheet("color: black")
            self.curPath_spiFlashUpdate = ""
            addLog('TabBar03', 'info', f"cancel spiFlashUpdate pack")

    def scanUDisk(self):
        usb_drives = get_usb_drives()
        if usb_drives:
            self.combo_box.clear()
            self.combo_box.addItem(" ")
            for drive in usb_drives:
                size_total = int(drive['size']) / (1024 ** 3)  # 转换为 GB
                size_free = int(drive['fssize']) / (1024 ** 3)  # 转换为 GB
                itemStr = f"{drive['device']} [{drive['fstype']}] ({size_free:.2f}GB/{size_total:.2f}GB)"
                self.combo_box.addItem(itemStr)
        else:
            self.combo_box.clear()
            self.combo_box.addItem(" ")

    def eventFilter(self, source, event):
        """事件过滤器：检测 QComboBox 的鼠标点击事件"""
        if source == self.combo_box and event.type() == QEvent.MouseButtonPress:
            self.scanUDisk()
        return super().eventFilter(source, event)

    def show_message(self, message, type=0):
        """显示提示消息框"""
        msg_box = QMessageBox()
        msg_box.setIcon(QMessageBox.Information)
        if type == 0:
            msg_box.setWindowTitle(getCNfromDict('megboxTitle-tip'))
        else:
            msg_box.setWindowTitle(getCNfromDict('megboxTitle-err'))
        msg_box.setText(message)
        msg_box.setStandardButtons(QMessageBox.Ok)
        msg_box.exec_()
